#ifndef  _DSC_H_
#define  _DSC_H_

//1 io cmd
#define IO_INIT_CMD  0
#define IO_CREAT_CRYPT_STREAM_CMD  1
#define IO_DELETE_CRYPT_STREAM_CMD  2
#define IO_KEY_INFO_UPDATE_CMD  3 
#define IO_GET_PID_POS_CMD  4 

#define IO_PARSE_DMX_ID_SET_CMD   0
#define IO_PARSE_DMX_ID_GET_CMD   1

#define IO_DSC_GET_DES_HANDLE     2
#define IO_DSC_GET_AES_HANDLE     3
#define IO_DSC_GET_CSA_HANDLE     4
#define IO_DSC_GET_SHA_HANDLE     5
#define IO_DSC_SET_PVR_KEY_PARAM  6
#define IO_DSC_ENCRYTP_BL_UK      7
#define IO_DSC_SET_PVR_KEY_IDLE   8
#define IO_DSC_SET_ENCRYPT_PRIORITY 10

#define DSC_TIMEOUT_FORVER		 0xFFFFFFFF
#define RAM_MON_SET_FLAG         0x00000002
#define RAM_MON_CLEAR_FLAG       0x00000001

#define ALI_INVALID_CRYPTO_STREAM_HANDLE  0xffffffff
#define ALI_INVALID_CRYPTO_KEY_POS			0xff
#define ALI_INVALID_CRYPTO_STREAM_ID		0xff
#define ALI_INVALID_DSC_SUB_DEV_ID          0xff

enum CSA_VERSION
{
    CSA1=1,
    CSA2=0,
    CSA3=2
};

enum SHA_MODE
{
SHA_SHA_1= 0,
SHA_SHA_224=(1<<29),
SHA_SHA_256=  (2<<29),
SHA_SHA_384 = (3<<29),
SHA_SHA_512  =(4<<29),
};

enum SHA_DATA_SOURCE
{
    SHA_DATA_SOURCE_FROM_DRAM =0,
    SHA_DATA_SOURCE_FROM_FLASH =1,
};

enum PARITY_MODE
{
    EVEN_PARITY_MODE  =0,
    ODD_PARITY_MODE =1,
    AUTO_PARITY_MODE0= 2,  /*for ts*/
    AUTO_PARITY_MODE1=3,
    OTP_KEY_FROM_68 = 4,
    OTP_KEY_FROM_6C = 5,
};

enum KEY_TYPE
{
    KEY_FROM_REG=0,
    KEY_FROM_SRAM=1,
    KEY_FROM_CRYPTO=2,
    KEY_FROM_OTP = 3,
};

enum KEY_MAP_MODE
{
   CSA_MODE=0,
   DES_MODE=0,
   CSA3_MODE=1,
   AES_128BITS_MODE=1,
   TDES_ABA_MODE=1,
   AES_192BITS_MODE=2,
   TDES_ABC_MODE=2,
   AES_256BITS_MODE=3
};

enum DMA_MODE
{
    PURE_DATA_MODE=0,
    TS_MODE=(1<<24),
};

enum RESIDUE_BLOCK
{
    RESIDUE_BLOCK_IS_NO_HANDLE = 0,
    RESIDUE_BLOCK_IS_AS_ATSC = (1 << 12),
    RESIDUE_BLOCK_IS_HW_CTS = (2 << 12),
    RESIDUE_BLOCK_IS_RESERVED = (3 << 12),
};


enum WORK_MODE
{
    WORK_MODE_IS_CBC=  0,
    WORK_MODE_IS_ECB =   (1<<4),
    WORK_MODE_IS_OFB=  (2<<4),
    WORK_MODE_IS_CFB  =(3<<4),   
    WORK_MODE_IS_CTR  =(4<<4),  /*only for aes*/
};

enum WORK_SUB_MODULE
{
    DES=0,
    TDES=3,
    AES=1,
    SHA=2,
    CSA=4,
};
//1 DES INIT PARAM
typedef struct des_init_param 
{
    enum PARITY_MODE  parity_mode;    
    enum KEY_TYPE key_from;
    UINT32 scramble_control;
    enum KEY_MAP_MODE key_mode;
    UINT32 stream_id; /**which stream id is working*/
    enum DMA_MODE dma_mode;
    enum RESIDUE_BLOCK  residue_mode;
    enum WORK_MODE work_mode;
    enum WORK_SUB_MODULE sub_module;
	UINT32 cbc_cts_enable ;  /*for pure data*/
}DES_INIT_PARAM, *pDES_INIT_PARAM;


//1 AES INIT PARAM
typedef struct aes_init_param 
{
    enum PARITY_MODE  parity_mode;    
    enum KEY_TYPE key_from;
    UINT32 scramble_control;
    enum KEY_MAP_MODE key_mode;
    UINT32 stream_id; /**which stream id is working*/
    enum DMA_MODE dma_mode;
    enum RESIDUE_BLOCK  residue_mode;
    enum WORK_MODE work_mode;
    UINT32 cbc_cts_enable ;  /*for pure data*/
}AES_INIT_PARAM, *pAES_INIT_PARAM;


//1 CSA INIT PARAM
typedef struct csa_init_param 
{
    enum CSA_VERSION version;
    enum DMA_MODE dma_mode;/*pure_data, or ts*/	 
    UINT32 Dcw[4];  /*for csa only used Dcw[0]Dcw[1], for csa3 used all*/
    UINT32 pes_en;  

    enum PARITY_MODE  parity_mode;    
    enum KEY_TYPE key_from;
    UINT32 scramble_control;
    UINT32 stream_id; /**which stream id is working*/  

}CSA_INIT_PARAM, *pCSA_INIT_PARAM;


//1 SHA INIT PARAM
typedef struct sha_init_param
{
  enum SHA_MODE sha_work_mode; 
  enum SHA_DATA_SOURCE sha_data_source;
} SHA_INIT_PARAM, *pSHA_INIT_PARAM;


struct AES_128Bit_KEY 
{
UINT8 even_key[16];
UINT8 odd_key[16];
};

struct AES_192Bit_KEY 
{
UINT8 even_key[24];
UINT8 odd_key[24];
};

struct AES_256Bit_KEY 
{
UINT8 even_key[32];
UINT8 odd_key[32];
};

typedef union aes_key_param
{
    struct AES_128Bit_KEY aes_128bit_key ;
    struct AES_192Bit_KEY aes_192bit_key ;
    struct AES_256Bit_KEY aes_256bit_key ;
   
}AES_KEY_PARAM;

typedef struct aes_iv_info
{
  UINT8 even_iv[16];
  UINT8 odd_iv[16];
}AES_IV_INFO;

struct  AES_KEY
{
   UINT8 OddKey[16];
   UINT8 EvenKey[16];
};

struct  CSA_KEY
{
   UINT8 OddKey[8];
   UINT8 EvenKey[8];
};

struct  CSA3_KEY
{
   UINT8 OddKey[16];
   UINT8 EvenKey[16];
};

typedef union csa_key_param
{
    struct  CSA_KEY csa_key ;
    struct  CSA3_KEY csa3_key ;
}CSA_KEY_PARAM;

struct  DES_64BITS_KEY_INFO
{
   UINT8 OddKey[8];
   UINT8 EvenKey[8];
};

struct  DES_128BITS_KEY_INFO
{
   UINT8 OddKey[16];
   UINT8 EvenKey[16];
};

struct  DES_192BITS_KEY_INFO
{
   UINT8 OddKey[24];
   UINT8 EvenKey[24];
};

typedef union des_key_param
{
   struct  DES_64BITS_KEY_INFO  des_64bits_key ;
   struct  DES_128BITS_KEY_INFO des_128bits_key ;
   struct  DES_192BITS_KEY_INFO des_192bits_key ;
   
}DES_KEY_PARAM;

typedef struct des_iv_info
{
  UINT8 even_iv[8];
  UINT8 odd_iv[8];
}DES_IV_INFO;

//1 KEY INFO PARAM
typedef struct  
{
    UINT32 handle ;  /* out parameter*/
    UINT16 *pid_list;
    UINT16 pid_len;  
    AES_KEY_PARAM *p_aes_key_info; /*for ts data mode*/
    CSA_KEY_PARAM *p_csa_key_info;
    DES_KEY_PARAM *p_des_key_info;
    UINT32 key_length;
    AES_IV_INFO *p_aes_iv_info;
    DES_IV_INFO *p_des_iv_info;
    UINT16 stream_id;
    
    UINT8 *init_vector; /*for pure data mode*/
    UINT8 *ctr_counter;
    UINT8 force_mode; /*user point the fix position*/
    UINT8 pos ;
}KEY_PARAM, *pKEY_PARAM;
//1 PID INFO PARAM
typedef struct pid_param
{  
   UINT32 dmx_id ;
   UINT16 pid;
   UINT16 pos;
}PID_POS_PARAM,*pPID_POS_PARAM ;

typedef struct ram_monitor_param
{
	UINT32 start_addr;
	UINT32 len;
	UINT32 interval;
	enum SHA_MODE sha_mode;
	BOOL   flag;
	ID ram_flg_id;
}RAM_MONITOR_PARAM,*pRAM_MONITOR_PARAM;

//1 SHA DEVICE
typedef struct sha_device
{
    struct sha_device  *next;  /*next device */
	/*struct module *owner;*/
	INT32 type;
	INT8 name[HLD_MAX_NAME_SIZE];
    void *pRoot;
    void *priv ; 
    void (*open)(struct sha_device *);
    void (*close)(struct sha_device *);
    RET_CODE (*digest)(struct sha_device * , UINT8 *, UINT8 *,UINT32 );
    RET_CODE  (*Ioctl)( struct sha_device * ,UINT32 cmd , UINT32 param);
    UINT8 id_number;	
}SHA_DEV,*pSHA_DEV;

//1 AES DEVICE
typedef struct aes_device
{
    struct aes_device  *next;  /*next device */
	/*struct module *owner;*/
	INT32 type;
	INT8 name[HLD_MAX_NAME_SIZE];
    void *pRoot;		/* Used to be 'private' but that upsets C++ */
    void *priv ;
    void (*open)(struct aes_device *);
    void (*close)(struct aes_device *);
    RET_CODE (*Encrypt)(struct aes_device * ,UINT16, UINT8 *, UINT8 *, UINT32 );
    RET_CODE (*Decrypt_cts)(struct aes_device * ,UINT16, UINT8 *, UINT8 *, UINT32, UINT8 * );
	RET_CODE (*Decrypt)(struct aes_device * ,UINT16, UINT8 *, UINT8 *, UINT32);
    RET_CODE (*Ioctl)(struct aes_device *,UINT32 cmd,UINT32 param);
    UINT8 id_number;
	
}AES_DEV,*pAES_DEV;


//1 DES DEVICE
typedef struct des_device
{
    struct des_device  *next;  /*next device */
	/*struct module *owner;*/
	INT32 type;
	INT8 name[HLD_MAX_NAME_SIZE];
    void *pRoot;		/* Used to be 'private' but that upsets C++ */
	void *priv ;
    void (*open)(struct des_device * );
    void (*close)(struct des_device *);
    RET_CODE (*Encrypt)(struct des_device *, UINT16,UINT8 *, UINT8 *, UINT32 );
	RET_CODE (*Decrypt_cts)(struct des_device *, UINT16,UINT8 *, UINT8 *, UINT32, UINT8 *);
	RET_CODE (*Decrypt)(struct des_device *, UINT16,UINT8 *, UINT8 *, UINT32 );
    RET_CODE (*Ioctl)(struct des_device *,UINT32 cmd,UINT32 param);
    UINT8 id_number;                 	
}DES_DEV,*pDES_DEV;


//1 CSA DEVICE
typedef struct csa_device
{
    struct csa_device  *next;  /*next device */
	/*struct module *owner;*/
	INT32 type;
	INT8 name[HLD_MAX_NAME_SIZE];
    void *pRoot;		/* Used to be 'private' but that upsets C++ */
    void *priv ;
    void (*open)(struct csa_device*);
    void (*close)(struct csa_device*);
    RET_CODE (*Decrypt)(struct csa_device*,UINT16, UINT8*, UINT8*, UINT32 );
    RET_CODE (*Ioctl)(struct csa_device *,UINT32 cmd,UINT32 param);
    UINT8 id_number;
}CSA_DEV,*pCSA_DEV;


//1 DSC DEVICE
typedef struct descrambler_device
{
	struct descrambler_device  *next;  /*next device */
	/*struct module *owner;*/
	INT32 type;
	INT8 name[HLD_MAX_NAME_SIZE];
	void *priv;		/*only point to SHA */
	UINT32 base_addr;
	UINT32  interrupt_id;

	
    void      (*attach)(void);
    void      (*detach)( struct descrambler_device *);
    RET_CODE	(*open)( struct descrambler_device *);
    RET_CODE   	(*close)( struct descrambler_device *);
    RET_CODE   (*ioctl)(struct descrambler_device *, UINT32 , UINT32 );
   
}DSC_DEV, *pDSC_DEV;

typedef struct DSC_PVR_KEY_PARAM
{
	UINT32 input_addr;
    UINT32 valid_key_num;
    UINT32 current_key_num;
    UINT32 pvr_key_length;
	UINT8 pvr_user_key_pos;
    UINT32 total_quantum_number; 
    UINT32 current_quantum_number;
    UINT32 ts_packet_number;
    UINT8 pvr_key_change_enable;
    UINT16 stream_id;
}DSC_PVR_KEY_PARAM,*pDSC_PVR_KEY_PARAM;

typedef struct DSC_BL_UK_PARAM
{
	UINT8 *input_key;
    UINT8 *r_key;
    UINT8 *output_key;
}DSC_BL_UK_PARAM,*pDSC_BL_UK_PARAM;



typedef struct DeEncrypt_config
{
	UINT32 do_encrypt ;
	void *dec_dev;                /*Decrypt device for stream*/
    UINT8 Decrypt_Mode;
	UINT16 dec_dmx_id;
    UINT32 do_decrypt ;
	void *enc_dev;                /*Encrypt device for stream*/
    UINT8 Encrypt_Mode;
	UINT16 enc_dmx_id;
}DEEN_CONFIG,*pDEEN_CONFIG;

typedef struct dsc_en_priority
{
	enum WORK_SUB_MODULE sub_module;
	enum PARITY_MODE priority;
    UINT32 dev_ptr; 
}DSC_EN_PRIORITY,*pDSC_EN_PRIORITY;

//1  API
void dsc_api_attach(void);
void des_open(pDES_DEV pDesDev );
void des_close(pDES_DEV pDesDev);
RET_CODE des_decrypt_cts(pDES_DEV pDesDev,UINT16 dmx_id,  UINT8 *input, UINT8 *output, UINT32 total_length,UINT8 *residue);
RET_CODE des_decrypt(pDES_DEV pDesDev,UINT16 dmx_id,  UINT8 *input, UINT8 *output, UINT32 total_length);
RET_CODE des_encrypt(pDES_DEV pDesDev,UINT16 dmx_id,  UINT8 *input, UINT8 *output, UINT32 total_length);
RET_CODE des_ioctl( pDES_DEV pDesDev ,UINT32 cmd , UINT32 param);

void aes_open(pAES_DEV pAesDev );
void aes_close(pAES_DEV pAesDev);
RET_CODE aes_decrypt_cts(pAES_DEV pAesDev,UINT16 dmx_id,  UINT8 *input, UINT8 *output, UINT32 total_length,UINT8 *residue);
RET_CODE aes_decrypt(pAES_DEV pAesDev,UINT16 dmx_id,  UINT8 *input, UINT8 *output, UINT32 total_length);
RET_CODE aes_encrypt(pAES_DEV pAesDev,UINT16 dmx_id,  UINT8 *input, UINT8 *output, UINT32 total_length);
RET_CODE aes_ioctl( pAES_DEV pAesDev ,UINT32 cmd , UINT32 param);

void csa_open(pCSA_DEV pCsaDev);
void csa_close(pCSA_DEV pCsaDev);
RET_CODE csa_decrypt(pCSA_DEV pCsaDev,UINT16 dmx_id,  UINT8 *input, UINT8 *output, UINT32 total_length);
RET_CODE csa_ioctl( pCSA_DEV pCsaDev ,UINT32 cmd , UINT32 param);

void sha_open(pSHA_DEV pShaDev);
void sha_close(pSHA_DEV pShaDev);
RET_CODE sha_ioctl( pSHA_DEV pShaDev ,UINT32 cmd , UINT32 param);
RET_CODE sha_digest(pSHA_DEV pShaDev, UINT8 *input, UINT8 *output,UINT32 data_length);

RET_CODE dsc_ioctl( pDSC_DEV pDscDev,UINT32 cmd , UINT32 param);
RET_CODE dsc_des_decrypt_cw_data(UINT8 cw_pos,UINT8 *in_data, UINT8 *out_data, UINT32 length);
RET_CODE trig_ram_mon(UINT32 start_addr,UINT32 end_addr, UINT32 interval, enum SHA_MODE sha_mode,BOOL DisableOrEnable);
RET_CODE DeEncrypt(pDEEN_CONFIG p_DeEn,UINT8 *input,UINT8 *output,UINT32 total_length);
UINT16 dsc_get_free_stream_id(enum DMA_MODE dma_mode);
UINT32 dsc_get_free_sub_device_id(enum WORK_SUB_MODULE sub_mode);
RET_CODE dsc_set_sub_device_id_idle(enum WORK_SUB_MODULE sub_mode,UINT32 device_id);
RET_CODE dsc_set_sub_device_id_used(enum WORK_SUB_MODULE sub_mode,UINT32 device_id);
RET_CODE dsc_set_stream_id_idle(UINT32 pos); 
void dsc_set_stream_id_used(UINT32 pos); 
RET_CODE dsc_deal_quantum_for_mixed_ts(pDEEN_CONFIG p_DeEn, UINT32 temp_length);

#endif  /*_DSC_H_*/
